package com.gitee.feizns.webtemplate.commons.rest;

import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.gitee.feizns.webtemplate.commons.exception.http.HttpException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * @author feizns
 * @since 2019/4/12
 */
@Configuration
@EnableConfigurationProperties(RestProperties.class)
public class RestAutoConfiguration {

    @Autowired
    private RestProperties properties;

    @ConditionalOnMissingBean(RestTemplate.class)
    @Bean
    public RestTemplate restTemplate() {
        SimpleClientHttpRequestFactory factory = simpleClientHttpRequestFactory();
        RestTemplate template = new RestTemplate(factory);
        template.getMessageConverters().add(0, fastJsonHttpMessageConverter());
        template.setErrorHandler(new DefaultResponseErrorHandler());
        return template;
    }

    private SimpleClientHttpRequestFactory simpleClientHttpRequestFactory() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setReadTimeout(properties.getReadTimeout());
        factory.setConnectTimeout(properties.getConnectTimeout());
        return factory;
    }

    private static final List<MediaType> MEDIA_TYPE_LIST = Arrays.asList(MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8, MediaType.TEXT_PLAIN);

    private FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        converter.setSupportedMediaTypes(MEDIA_TYPE_LIST);
        return converter;
    }

    /**
     * 默认的错误处理器
     */
    private static class DefaultResponseErrorHandler implements ResponseErrorHandler {

        @Override
        public boolean hasError(ClientHttpResponse response) throws IOException {
            return true;
        }

        @Override
        public void handleError(ClientHttpResponse response) throws IOException {
            if ( response.getStatusCode() != HttpStatus.OK )
                throw new HttpException(response.getStatusText(), response.getStatusCode());
        }

    }

}
